package borge.web.teamspirit.client.page.team.panels;

import java.io.Serializable;
import java.util.HashMap;

import borge.web.teamspirit.client.SessionData;
import borge.web.teamspirit.client.data.Match;
import borge.web.teamspirit.client.data.News;
import borge.web.teamspirit.client.data.Person;
import borge.web.teamspirit.client.data.Serie;
import borge.web.teamspirit.client.data.Team;
import borge.web.teamspirit.client.data.TeamPlayer;
import borge.web.teamspirit.client.interfaces.DataProvider;
import borge.web.teamspirit.client.interfaces.PanelHandler;
import borge.web.teamspirit.client.interfaces.PersistentData;
import borge.web.teamspirit.client.interfaces.ServerCallbackHandler;
import borge.web.teamspirit.client.interfaces.WidgetEventHandler;
import borge.web.teamspirit.client.page.shared.widgets.CreateDataWidget;
import borge.web.teamspirit.client.page.shared.widgets.CreatePersonWidget;
import borge.web.teamspirit.client.page.shared.widgets.CreateTeamWidget;
import borge.web.teamspirit.client.page.team.TokenData;
import borge.web.teamspirit.client.page.team.widgets.CreateMatchWidget;
import borge.web.teamspirit.client.page.team.widgets.CreatePlayerWidget;
import borge.web.teamspirit.client.page.team.widgets.CreateSerieWidget;
import borge.web.teamspirit.client.servercomm.DBQueryResults;
import borge.web.teamspirit.client.servercomm.ServerComm;

import com.google.gwt.user.client.Window;

/**
 * Panel for widgets that have FormCreatorWidget as common superclass
 * @author Andreas Borglin
 *
 */
public class CreateEditPanel extends MiddlePanel implements WidgetEventHandler, 
                                                                ServerCallbackHandler {

    private CreateDataWidget iActiveWidget;
    private DataProvider iDataProvider;
    
    private Serializable iData;
    
	private HashMap<String, CreateDataWidget> iTokenMap;
    
    public CreateEditPanel(/*ServerComm aComm,*/ PanelHandler aPanelHandler){
    	super(/*aComm,*/ aPanelHandler);

    	iTokenMap = new HashMap<String, CreateDataWidget>();
    }
    
    public void setActiveWidget(CreateDataWidget aWidget){
        if(iActiveWidget != null)
            remove(iActiveWidget);
        
        iActiveWidget = aWidget;
        iActiveWidget.setWidgetEventHandler(this);
        add(iActiveWidget);
    }
    
    public void setDataProvider(DataProvider aDataProvider){
        iDataProvider = aDataProvider;
    }
    
    public void handleWidgetEvent(WidgetEventType aEvent){
        
        switch(aEvent){
        
        // Can't we use generics here or something..?
        
//        case EDIT_PLAYER: {
//            // 
//        	Team team = new Team();
//        	team.setName("Test team");
//            TeamPlayer player = iDataProvider.getDataObject();
//            setActiveWidget(new CreatePlayerWidget(this, team, player));
//            break;
//        }
//        case EDIT_SERIE: {
//            
//            Serie serie = iDataProvider.getDataObject();
//            //setActiveWidget(new CreateSerieWidget(this, serie));
//            break;
//        }
//        
//        case EDIT_MATCH: {
//            Match match = iDataProvider.getDataObject();
//            setActiveWidget(new CreateMatchWidget(this, match));
//            break;
//        }
//        
//        case EDIT_PERSON: {
//        	Person person = iDataProvider.getDataObject();
//        	setActiveWidget(new CreatePersonWidget(this, person));
//        }
        
        case TEAM_CREATED: {
        	
        	Team team = iActiveWidget.getDataObject();
        	
        	team = Team.createTeamFromUserForm(team, iActiveWidget.getUserContentProvider());
        	
        	if(iActiveWidget.getUserContentProvider().foundInputErrors()){
                iActiveWidget.addErrorWidget();
                return;
            }
        	
        	if(SessionData.sLoggedInUser == null){
        		Window.alert("Not logged in");
        		return;
        	}
        	
        	team.setOwner(SessionData.sLoggedInUser.getEncodedKey());
        	
        	iData = team;
        	
        	ServerComm.saveObject(team, this);
        	//DBQuery<Team> query = new DBQuery<Team>(Team.class.getName());
        	//query.addFilter("iName", DBQuery.EQUALS, "nameParam", "String", team.getName(), null);
        	//ServerComm.isFieldUnique(query, this);
        	
        	break;
        }
        
        case PERSON_CREATED: {
        	
        	Person person = iActiveWidget.getDataObject();
        	person = Person.createPersonFromUserForm(person, iActiveWidget.getUserContentProvider());
        	
        	if(iActiveWidget.getUserContentProvider().foundInputErrors()){
                iActiveWidget.addErrorWidget();
                return;
            }
        	
        	ServerComm.saveObject(person, this);
        	
        	break;
        }
        
        case PLAYER_CREATED:  {
            
            // Handles both create and update
            TeamPlayer player = iActiveWidget.getDataObject();
            player = TeamPlayer.createPlayerFromUserForm(player, iActiveWidget.getUserContentProvider());
            //Window.alert(player.dumpContent());
            
            if(iActiveWidget.getUserContentProvider().foundInputErrors()){
                iActiveWidget.addErrorWidget();
                return;
            }
            ServerComm.saveObject(player, this);
            //handleDataObject(player);

            break;
        }
        case MATCH_CREATED: {
            Match match = iActiveWidget.getDataObject();
            match = Match.createMatchFromUserForm(match, iActiveWidget.getUserContentProvider());
            Window.alert(match.dumpContent());
            
            //handleDataObject(match);
            if(iActiveWidget.getUserContentProvider().foundInputErrors()){
                iActiveWidget.addErrorWidget();
                return;
            }
            
            ServerComm.saveObject(match, this);
            
            break;
        }
        case SERIE_CREATED: {
            Serie serie = iActiveWidget.getDataObject();
            serie = Serie.createSerieFromUserForm(serie, iActiveWidget.getUserContentProvider());
            //Window.alert(serie.dumpContent());
            
            //handleDataObject(serie);
            if(iActiveWidget.getUserContentProvider().foundInputErrors()){
                iActiveWidget.addErrorWidget();
                return;
            }
            
            ServerComm.saveObject(serie, this);
            
            break;
        }
        case NEWS_CREATED: {
            News news = News.createNewsFromUserForm(iActiveWidget.getUserContentProvider());
            Window.alert(news.dumpContent());
            
            //handleDataObject(news);
        }
        }
        
        
    }
    

    
    public void handleServerCallback(DBQueryResults aResult, CallbackType aType){
        
    	//Window.alert("callback");
        // Let widget do its stuff
    	switch(aType){
    	case CREATED: {
    	
    		if(aResult.querySucceeded())
    			iActiveWidget.handleSuccess();
            else
            	iActiveWidget.handleFailure();    
    		break;
    	}
    	case UNIQUE_DATA: {
    		
    		if(aResult.querySucceeded()){
    			ServerComm.saveObject((PersistentData)iData, this); // this cast might be trouble?
    		}
    		else{
    			Window.alert("Already exists with that field");
    		}
    		
    		break;
    	}
    	}
        
        
        // What should we do here? 
        //List<Player> list = (List<Player>)aResult.getResultList();
    }
    
    public void handleServerError(Throwable t){
        Window.alert("Server error: " + t.toString());
       t.printStackTrace();
    }
    
    private CreateDataWidget createWidget(String aToken){
    	
    	CreateDataWidget widget = null;
    	if(aToken.equals(TokenData.PERSON)){
    		widget = new CreatePersonWidget(this);
    	}
    	else if(aToken.equals(TokenData.TEAM)){
    		widget = new CreateTeamWidget(this);
    	}
    	else if(aToken.equals(TokenData.SERIE)){
    		widget = new CreateSerieWidget(this);
    	}
    	else if(aToken.equals(TokenData.PLAYER)){
    		widget = new CreatePlayerWidget(this);
    	}
    	else if(aToken.equals(TokenData.MATCH)){
    		widget = new CreateMatchWidget(this);
    	}
    	else
    		Window.alert("Unknown widget token: " + aToken);
    	return widget;
    	
    	
    }

	@Override
	public void forwardToken(String aWidget, String aData) {
		
		CreateDataWidget widget = iTokenMap.get(aWidget);
		
		if(widget == null){
			widget = createWidget(aWidget);
			// TODO: Handle widget null here or in create?
			iTokenMap.put(aWidget, widget);
		}

		widget.updateData();
		
		setActiveWidget(widget);

		
	}
    
    
    
}
